home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / uhren & terminkalender / time / sclock / source / analog.c next >
C/C++ Source or Header  |  1996-04-07  |  10KB  |  464 lines

  1. /****************************************************************************
  2. *
  3. * VERSION
  4. *    $VER: analog.c 1.66 (08.12.93)
  5. *
  6. * DESCRIPTION
  7. *    Analog clock display code...
  8. *
  9. * AUTHOR
  10. *    Rune Johnsrud
  11. *
  12. * COPYRIGHT
  13. *    (c) 1993 Amiga Freelancers
  14. *
  15. *****************************************************************************/
  16.  
  17. #include <graphics/gfxmacros.h>
  18. #include <exec/types.h>
  19. #include <exec/memory.h>
  20. #include <utility/date.h>
  21.  
  22. #include <proto/exec.h>
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <proto/diskfont.h>
  26. #include <proto/gadtools.h>
  27. #include <proto/layers.h>
  28.  
  29. #include "global.h"
  30.  
  31. /****************************************************************************/
  32.  
  33. extern struct GlobalData *gd;
  34. extern struct ClockInfo *ci;
  35. extern struct Gadget ClockGadget;
  36. extern WORD SinTab[60];
  37. extern WORD CosTab[60];
  38.  
  39. /****************************************************************************/
  40.  
  41. struct RectPoints
  42. {
  43.     WORD x;
  44.     WORD y;
  45.     WORD w;
  46.     WORD h;
  47. };
  48.  
  49. #define NUM_OF_VECTORS        100
  50. #define MAXVECTORS             NUM_OF_VECTORS / 5
  51. #define MINTERM_VCOPY         0xC0
  52. #define CB_COPY                TRUE
  53. #define CB_PASTE            FALSE
  54. #define DT_RENDER_BITMAP    TRUE
  55. #define DT_GET_ATTRS        FALSE
  56. #define DIV_SCALER            1024
  57.  
  58. /****************************************************************************/
  59.  
  60. static VOID CalcWinDims(VOID);
  61. static WORD DrawClock(VOID);
  62. static VOID DrawTimeI(WORD x, WORD y, UBYTE pen);
  63.  
  64. static VOID SortBlitPoints(WORD x, WORD y, WORD w, WORD h, struct RectPoints *p);
  65. static VOID BlitClip(WORD x, WORD y, WORD ox, WORD oy, BOOL source);
  66.  
  67. static VOID SaveDisplay(VOID);
  68. static VOID RestoreDisplay(VOID);
  69.  
  70. WORD CreateAnalogClock(VOID);
  71. VOID RefreshAnalogClock(VOID);
  72. WORD DeleteAnalogClock(VOID);
  73.  
  74. /****************************************************************************/
  75.  
  76.  
  77. static VOID CalcWinDims(VOID)
  78. {
  79.     if (ci->WinBevel)
  80.     {
  81.         ci->InnerTop    = 1;
  82.         ci->InnerLeft   = 1;
  83.         ci->InnerWidth  = ci->Width  - 1;
  84.         ci->InnerHeight = ci->Height - 1;
  85.     }
  86.     else
  87.     {
  88.         ci->InnerTop    = 0;
  89.         ci->InnerLeft   = 0;
  90.         ci->InnerWidth  = ci->Width;
  91.         ci->InnerHeight = ci->Height;
  92.     }
  93.  
  94.     if (ci->PlaceClock)
  95.     {
  96.         ci->ap.CtX = ((ci->ap.ClockLeft + ci->ap.ClockWidth)  / 2);
  97.         ci->ap.CtY = ((ci->ap.ClockTop  + ci->ap.ClockHeight) / 2);
  98.         ci->ap.SzX = (ci->ap.ClockWidth  / 2);
  99.         ci->ap.SzY = (ci->ap.ClockHeight / 2);
  100.  
  101.         if (ci->ap.SzX > (ci->Width / 2))
  102.             ci->ap.SzX = (ci->Width / 2);
  103.  
  104.         if (ci->ap.SzY > (ci->Height / 2))
  105.             ci->ap.SzY = (ci->Height / 2);
  106.  
  107.         if ((ci->ap.CtX + ci->ap.SzX) >= ci->Width)
  108.             ci->ap.CtX = (ci->Width - ci->ap.SzX) - 1;
  109.  
  110.         if ((ci->ap.CtY + ci->ap.SzY) >= ci->Height)
  111.             ci->ap.CtY = (ci->Height - ci->ap.SzY) - 1;
  112.     }
  113.     else
  114.     {
  115.         ci->ap.CtX = (ci->InnerWidth  / 2);
  116.         ci->ap.CtY = (ci->InnerHeight / 2);
  117.         ci->ap.SzX = (ci->ap.CtX - ci->EdgeSpace);
  118.         ci->ap.SzY = (ci->ap.CtY - ci->EdgeSpace);
  119.     }
  120.  
  121.     ci->ap.SzX -= (ci->ap.SzX / ci->ap.MIXScale);
  122.     ci->ap.SzY -= (ci->ap.SzY / ci->ap.MIYScale);
  123.  
  124.     if (ci->ShowDial)
  125.     {
  126.         ci->ap.SzX -= 2;
  127.         ci->ap.SzY -= 2;
  128.     }
  129.  
  130.     ci->ap.Dec = ((ci->ap.SzX + ci->ap.SzY) / 5);
  131. }
  132.  
  133.  
  134. static WORD DrawClock(VOID)
  135. {
  136.     struct RastPort *rp = gd->ClockWindow->RPort;
  137.     struct TmpRas tmpras;
  138.     struct AreaInfo areainfo;
  139.     VOID *rasdata = NULL;
  140.     WORD *vecbuff = NULL;
  141.     ULONG rsize;
  142.     WORD a, x, y, sx, sy, errcode = NOERROR;
  143.  
  144.     sx = (ci->ap.SzX / ci->ap.MIXScale);
  145.     sy = (ci->ap.SzY / ci->ap.MIYScale);
  146.  
  147.     if (ci->ShowDial)
  148.     {
  149.         rsize   = RASSIZE(ci->Width, ci->Height);
  150.         rasdata = (VOID *) AllocVec(rsize, MEMF_CHIP);
  151.         vecbuff = (WORD *) AllocVec(NUM_OF_VECTORS, MEMF_CLEAR);
  152.  
  153.         if (rasdata && vecbuff)
  154.         {
  155.             InitTmpRas(&tmpras, rasdata, rsize);
  156.             rp->TmpRas = &tmpras;
  157.  
  158.             InitArea(&areainfo, vecbuff, MAXVECTORS);
  159.             rp->AreaInfo = &areainfo;
  160.  
  161.             SetAPen(rp, ci->apn.DialOPen);
  162.             AreaEllipse(rp, ci->ap.CtX, ci->ap.CtY, 2 + ci->ap.SzX + sx, 2 + ci->ap.SzY + sy);
  163.             AreaEnd(rp);
  164.  
  165.             SetAPen(rp, ci->apn.DialPen);
  166.             AreaEllipse(rp, ci->ap.CtX, ci->ap.CtY, 1 + ci->ap.SzX + sx, 1 + ci->ap.SzY + sy);
  167.             AreaEnd(rp);
  168.         }
  169.         else
  170.             errcode = GEN_ERR_ALLOCMEM;
  171.  
  172.         if (rasdata)
  173.         {
  174.             FreeVec(rasdata);
  175.             rp->TmpRas = NULL;
  176.         }
  177.  
  178.         if (vecbuff)
  179.         {
  180.             FreeVec(vecbuff);
  181.             rp->AreaInfo = NULL;
  182.         }
  183.     }
  184.  
  185.     SetAPen(rp, ci->apn.MinSmallPen);
  186.     for (a=0; a<60; a++)
  187.     {
  188.         x = ci->ap.CtX + ((SinTab[a] * ci->ap.SzX) / DIV_SCALER);
  189.         y = ci->ap.CtY - ((CosTab[a] * ci->ap.SzY) / DIV_SCALER);
  190.  
  191.         WritePixel(rp, x, y);
  192.     }
  193.  
  194.     SetAPen(rp, ci->apn.MinLargePen);
  195.     for (a=0; a<60; a+=5)
  196.     {
  197.         x = ci->ap.CtX + ((SinTab[a] * ci->ap.SzX) / DIV_SCALER);
  198.         y = ci->ap.CtY - ((CosTab[a] * ci->ap.SzY) / DIV_SCALER);
  199.  
  200.         RectFill(rp, x - sx, y - sy, x + sx, y + sy);
  201.     }
  202.  
  203.     return errcode;
  204. }
  205.  
  206.  
  207. static VOID DrawTimeI(WORD x, WORD y, UBYTE pen)
  208. {
  209.     struct RastPort *rp = gd->ClockWindow->RPort;
  210.  
  211.     SetAPen(rp, pen);
  212.     Move(rp, ci->ap.CtX, ci->ap.CtY);
  213.     Draw(rp, x, y);
  214. }
  215.  
  216.  
  217. WORD CreateAnalogClock(VOID)
  218. {
  219.     struct Gadget *g = &ClockGadget;
  220.     struct RastPort *rp;
  221.     UBYTE depth;
  222.  
  223.     if (gd->ClockWindow) CleanUpClock();
  224.  
  225. //    gd->TextFont = OpenDiskFont(&gd->TextAttr);
  226. //    if (!gd->TextFont) return GEN_ERR_OPENFONT;
  227.  
  228.     gd->VScreen = LockPubScreen(ci->PubScreenName);
  229.     if (!gd->VScreen) return GEN_ERR_LOCKSCREEN;
  230.  
  231.     gd->VisualInfo = GetVisualInfo(gd->VScreen, NULL);
  232.     if (!gd->VisualInfo) return GEN_ERR_GETVISUALINFO;
  233.  
  234.     if ((ci->AutoSize) && (ci->BDRPic)) Error("Datatypes", ReadDTPic(DT_GET_ATTRS));
  235.  
  236.     CalcWinDims();
  237.  
  238.     gd->ClockWindow = OpenWindowTags(NULL,
  239.                         WA_PubScreen,    gd->VScreen,
  240.                         WA_Top,            ci->Top,
  241.                         WA_Left,        ci->Left,
  242.                         WA_InnerWidth,    ci->Width,
  243.                         WA_InnerHeight,    ci->Height,
  244.                         WA_Activate,    TRUE,
  245.                         WA_Borderless,    TRUE,
  246.                         WA_Backdrop,    ci->BDClock,
  247.                         WA_DragBar,        FALSE,
  248.                         WA_NewLookMenus,TRUE,
  249.                         WA_IDCMP,        IDCMP_MENUPICK | IDCMP_IDCMPUPDATE,
  250.                         TAG_DONE);
  251.  
  252.     if (!gd->ClockWindow) return GEN_ERR_OPENWINDOW;
  253.  
  254.     depth = GetBitMapAttr(gd->VScreen->RastPort.BitMap, BMA_DEPTH);
  255.  
  256.     gd->SaveBM = AllocBitMap(ci->Width, ci->Height, depth, BMF_INTERLEAVED, NULL);
  257.     if (!gd->SaveBM) return GEN_ERR_ALLOCMEM;
  258.  
  259.     InitRastPort(&gd->SaveRP);
  260.     gd->SaveRP.BitMap = gd->SaveBM;
  261.  
  262.     if (!InitMainMenus()) return GEN_ERR_MENUS;
  263.  
  264.     g->Width          = ci->InnerWidth;
  265.     g->Height         = ci->InnerHeight;
  266.     gd->ClockGadget = g;
  267.     rp                 = gd->ClockWindow->RPort;
  268.  
  269. //    gd->FillRP = *rp;
  270. //    SetAPen(&gd->FillRP, ci->BGPen);
  271.  
  272.     SetAPen(rp, ci->BGPen);
  273.     RectFill(rp, 0, 0, ci->InnerWidth, ci->InnerHeight);
  274.  
  275.     if (ci->WinBevel)
  276.     {
  277.         SetAPen(rp, ci->ShinePen);
  278.         Move(rp, 0, ci->InnerHeight);
  279.         Draw(rp, 0, 0);
  280.         Draw(rp, ci->InnerWidth, 0);
  281.  
  282.         SetAPen(rp, ci->ShadowPen);
  283.         Move(rp, ci->InnerWidth, 1);
  284.         Draw(rp, ci->InnerWidth, ci->InnerHeight);
  285.         Draw(rp, 0, ci->InnerHeight);
  286.  
  287.         ci->InnerWidth--;
  288.         ci->InnerHeight--;
  289.     }
  290.  
  291.     if (ci->BDRPic) Error("Datatypes", ReadDTPic(DT_RENDER_BITMAP));
  292.  
  293.     if (gd->VScreen)
  294.     {
  295.         UnlockPubScreen(NULL, gd->VScreen);
  296.         gd->VScreen = NULL;
  297.     }
  298.  
  299.     Error("Draw Clock", DrawClock());
  300.  
  301. //    SetABPenDrMd(rp, ci->TextPen, ci->BGPen, JAM2);
  302. //    SetFont(rp, gd->TextFont);
  303.  
  304.     AddGadget   (gd->ClockWindow, gd->ClockGadget, -1);
  305.     RefreshGList(gd->ClockGadget, gd->ClockWindow, NULL, -1);
  306.  
  307.     gd->CData.min  = 99;
  308.     gd->CData.hour = 99;
  309.  
  310.     GetCurrSysTime();
  311.     SaveDisplay();
  312.     RefreshAnalogClock();
  313.  
  314.     return NOERROR;
  315. }
  316.  
  317.  
  318. static VOID SortBlitPoints(WORD x, WORD y, WORD w, WORD h, struct RectPoints *p)
  319. {
  320.     if (x <= w)
  321.     {
  322.         p->x = x - 1;
  323.         p->w = w + 1;
  324.     }
  325.     else
  326.     {
  327.         p->x = w - 1;
  328.         p->w = x + 1;
  329.     }
  330.  
  331.     if (y <= h)
  332.     {
  333.         p->y = y - 1;
  334.         p->h = h + 1;
  335.     }
  336.     else
  337.     {
  338.         p->y = h - 1;
  339.         p->h = y + 1;
  340.     }
  341. }
  342.  
  343.  
  344. static VOID BlitClip(WORD x, WORD y, WORD ox, WORD oy, BOOL source)
  345. {
  346.     struct RectPoints p;
  347.     struct RastPort *rp = gd->ClockWindow->RPort;
  348.  
  349.     SortBlitPoints(x, y, ci->ap.CtX, ci->ap.CtY, &p);
  350.  
  351.     if (source)
  352.     {
  353.         ClipBlit(rp, p.x, p.y, &gd->SaveRP, ox, oy,
  354.                 (p.w - p.x), (p.h - p.y), MINTERM_VCOPY);
  355.     }
  356.     else
  357.     {
  358.         ClipBlit(&gd->SaveRP, ox, oy, rp, p.x, p.y,
  359.                 (p.w - p.x), (p.h - p.y), MINTERM_VCOPY);
  360.     }
  361. }
  362.  
  363.  
  364. static VOID SaveDisplay(VOID)
  365. {
  366.     WORD i;
  367.  
  368.     if (ci->ShowSec)
  369.     {
  370.         i         = gd->CData.sec;
  371.         ci->ap.sx = ci->ap.CtX + ((SinTab[i] * ci->ap.SzX) / DIV_SCALER);
  372.         ci->ap.sy = ci->ap.CtY - ((CosTab[i] * ci->ap.SzY) / DIV_SCALER);
  373.  
  374.         BlitClip(ci->ap.sx, ci->ap.sy, 0, 0, CB_COPY);
  375.     }
  376.  
  377.     if (gd->NewMin)
  378.     {
  379.         i         = gd->CData.min;
  380.         ci->ap.mx = ci->ap.CtX + ((SinTab[i] * ci->ap.SzX) / DIV_SCALER);
  381.         ci->ap.my = ci->ap.CtY - ((CosTab[i] * ci->ap.SzY) / DIV_SCALER);
  382.  
  383.         BlitClip(ci->ap.mx, ci->ap.my, (ci->Width / 2), 0, CB_COPY);
  384.  
  385.         gd->NewMin = FALSE;
  386.     }
  387.  
  388.     if (gd->NewHour)
  389.     {
  390.         i         = (((gd->CData.hour % 12) * 5) + (gd->CData.min / 12));
  391.         ci->ap.hx = ci->ap.CtX + ((SinTab[i] * (ci->ap.SzX - ci->ap.Dec)) / DIV_SCALER);
  392.         ci->ap.hy = ci->ap.CtY - ((CosTab[i] * (ci->ap.SzY - ci->ap.Dec)) / DIV_SCALER);
  393.  
  394.         BlitClip(ci->ap.hx, ci->ap.hy, 0, (ci->Height / 2), CB_COPY);
  395.  
  396.         gd->NewHour = FALSE;
  397.     }
  398. }
  399.  
  400.  
  401. static VOID RestoreDisplay(VOID)
  402. {
  403.     if (ci->ShowSec)
  404.         BlitClip(ci->ap.sx, ci->ap.sy, 0, 0, CB_PASTE);
  405.  
  406.     if (gd->NewMin)
  407.         BlitClip(ci->ap.mx, ci->ap.my, (ci->Width / 2), 0, CB_PASTE);
  408.  
  409.     if (gd->NewHour)
  410.         BlitClip(ci->ap.hx, ci->ap.hy, 0, (ci->Height / 2), CB_PASTE);
  411. }
  412.  
  413.  
  414. VOID RefreshAnalogClock(VOID)
  415. {
  416.     GetCurrSysTime();
  417.  
  418.     RestoreDisplay();
  419.     SaveDisplay();
  420.  
  421.     if (ci->ShowSec)
  422.     {
  423.         DrawTimeI(ci->ap.hx, ci->ap.hy, ci->apn.HourPen);
  424.         DrawTimeI(ci->ap.mx, ci->ap.my, ci->apn.MinPen);
  425.         DrawTimeI(ci->ap.sx, ci->ap.sy, ci->apn.SecPen);
  426.     }
  427.  
  428.     if (gd->NewTime)
  429.     {
  430.         DrawTimeI(ci->ap.hx, ci->ap.hy, ci->apn.HourPen);
  431.         DrawTimeI(ci->ap.mx, ci->ap.my, ci->apn.MinPen);
  432.  
  433.         gd->NewTime = FALSE;
  434.     }
  435. }
  436.  
  437.  
  438. WORD DeleteAnalogClock(VOID)
  439. {
  440.     ci->Top  = gd->ClockWindow->TopEdge;
  441.     ci->Left = gd->ClockWindow->LeftEdge;
  442.  
  443.     if (gd->VScreen)     UnlockPubScreen(NULL, gd->VScreen);
  444.     if (gd->SaveBM)         FreeBitMap(gd->SaveBM);
  445.     if (gd->ClockGadget) RemoveGadget(gd->ClockWindow, gd->ClockGadget);
  446. //    if (gd->TextFont)    CloseFont(gd->TextFont);
  447.     if (gd->ClockWindow) ClearMenuStrip(gd->ClockWindow);
  448.     if (gd->MainMenu)     FreeMenus(gd->MainMenu);
  449.     if (gd->VisualInfo)     FreeVisualInfo(gd->VisualInfo);
  450.     if (gd->ClockWindow) CloseWindow(gd->ClockWindow);
  451.  
  452.     gd->VScreen     = NULL;
  453.     gd->ClockGadget = NULL;
  454.     gd->VisualInfo  = NULL;
  455.     gd->MainMenu    = NULL;
  456. //    gd->TextFont    = NULL;
  457.     gd->ClockWindow = NULL;
  458.  
  459.     return NOERROR;
  460. }
  461.  
  462.  
  463. /* End Of File */
  464.